import requests
import re
from urllib import parse
import os
from lxml import etree
from datetime import datetime
from threading import Thread

import read_excel

class DownloadPicture:

    def __init__(self,keyword,page=1): #初始化参数
        self.keyword = keyword
        self.url_keyword = parse.quote(keyword)
        self.pn = page
        self.session = requests.session()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6776.400 QQBrowser/10.3.2577.400'
        }

    def request_url(self): #模拟首次图片请求
        url = 'https://www.baidu.com/s?wd={}#tn=simple'.format(self.url_keyword)
        resp = self.session.get(url,headers=self.headers,verify=False)
        resp.encoding = 'utf8'
        # res = re.findall(r'<a href="(.*?)" target="_blank">',resp.text)[0]
        res = self.ruler_xpath(resp.text,'//div[@id="s_tab"]/div[@class="s_tab_inner"]/a[@class="s-tab-item s-tab-pic"]/@href')
        if res:
            res = res[0]
        else:
            res = self.ruler_xpath(resp.text,'//*[@id="content_left"]/div[@tpl="img_normal"]/div/h3/a/@href')
            if res:
                res = res[0]
            else:
                res = self.ruler_xpath(resp.text, '//*[@id="s_tab"]/div[@class="s_tab_inner"]/a[3]/@href')[0]
        result = self.session.get(res,headers = self.headers,verify=False)
        self.referer = 'http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1550747834305_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&hs=2&word={}&f=3&rsp=1'.format(self.url_keyword)
        data = result.content.decode() #首次请求未滑动之前获取的网页文本
        # print(self.referer)
        return data

    def ruler_xpath(self,res,ruler):
        return etree.HTML(res).xpath(ruler)

    def requests_slide_url(self,gsm,page): #模拟向下滑动请求（和翻页差不多）
        # url = 'http://image.baidu.com/search/acjson'
        url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10554456809307074698&ipn=rj&ct=201326592&is=&fp=result&queryWord={0}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=&copyright=&word={0}&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=&fr=&expermode=&nojc=&pn={1}&rn=30&gsm={2}&1626917151892='.format(self.keyword,(page-1)*30,gsm)
        # params = {
        #     'tn':'resultjson_com',
        #     'ipn':'rj',
        #     'ct':'201326592',
        #     'is':'',
        #     'fp':'result',
        #     'queryWord': self.keyword,
        #     'cl':'2',
        #     'lm': '-1',
        #     'ie':'utf-8',
        #     'oe':'utf-8',
        #     'adpicid':'',
        #     'st':'',
        #     'z':'',
        #     'ic':'',
        #     'hd':'',   # 这个参数为:'1' 代表下载高清图片
        #     'latest':'1', # 这个参数为:'1' 代表下载最新图片    注意：'hd'和'latest'不能同时为'1'
        #     'copyright':'',
        #     'word':self.keyword,
        #     's':'',
        #     'se':'',
        #     'tab':'',
        #     'width':'',
        #     'height':'',
        #     'face':'',
        #     'istype':'',
        #     'qc':'',
        #     'nc':'',
        #     'fr':'',
        #     'expermode':'',
        #     'force':'',
        #     'pn':(page-1)*30,
        #     'rn':'30',
        #     'gsm':gsm,
        #     '1550746139308':'',
        # }
        slide_image_text = self.session.get(url,headers=self.headers,verify=False).content.decode()
        return slide_image_text

    def parse_rule(self, target_url, page): #提取图片的url列表,以及requests_slide_url方法所需的参数gsm
        image_url_list = re.findall(r'"thumbURL":"(.*?)"', target_url)
        print(image_url_list)
        try:
            if page == 1:
                gsm = re.findall(r"app.setPageInfo.*?gsm: '(.*?)'.*?", target_url, re.S)
                self.headers['Referer'] = self.referer
            else:
                gsm = re.findall(r'"gsm":"(.*?)"', target_url)
            return image_url_list, gsm[0]
        except Exception as e:
            print(f'gsm参数获取失败！--{e}')


    def save_image_file(self,i):#保存图片到文件  为多线程创建
        file_dir = 'D:\\project\\project_6\\baidu_picture\\{}'.format(self.keyword)
        file_name = os.path.join(file_dir, i.split('/')[-1])#文件路径
        if not os.path.exists(file_dir):
            try:
                os.makedirs(file_dir)
            except FileExistsError:
                pass
        image = self.session.get(i, headers=self.headers, verify=False).content
        with open(file_name, 'wb') as f:
            f.write(image)

    def save_image(self,image_url,page): #保存图片
        for i in image_url:
            if 'jpg' in i:
                Thread(target=self.save_image_file, args=(i,)).start()
                # print(i)
                # list_name = os.listdir('D:\\project_two\\shangwu_picture\\baidu')
                # list_name_2 = os.listdir('D:\\jinyinzhizhao\\无水印执照')
                # list_name.extend(list_name_2)
                # file_name = i.split('/')[-1]
                # if file_name not in list_name:
                #     Thread(target=self.save_image_file,args=(i,)).start()
                # else:
                #     print('重复了--',file_name)
            else:
                continue
        print(f'第{page}页下载完成！')

    def image_page(self,page):  #控制图片下载页数
        biao = 0
        resp = self.request_url()
        image_url_list, gsm = self.parse_rule(resp,1)
        # print(image_url_list)
        self.save_image(image_url_list,1)
        for i in range(2,page+1):
            slide_image_text = self.requests_slide_url(gsm,i)
            image_url_list, gsm = self.parse_rule(slide_image_text,i)
            if not image_url_list:
                biao += 1
                if biao <= 5:
                    continue
                else:
                    break
            self.save_image(image_url_list,i)
            # print(image_url_list)

    def run(self):
        self.image_page(self.pn)

def timer(a):
    def nq(*args):
        time1 = datetime.now()
        a(*args)
        time2 = datetime.now()
        time_m = time2 - time1
        print('下载时间为：{}'.format(time_m))
    return nq

if __name__ == '__main__':
    @timer
    def db_picture(content,page=1):
        d = DownloadPicture(content,page)
        d.run()
    # content = input('请输入你要搜索的图片的关键字：')
    # page =int(input('请输入你要下载的图片的页数(一页等于30张图片)：'))
    while True:
        try:
            db_picture('武术大刀',50)
            break
        except Exception as e:
            pass
